<template>
    <a-modal
        v-model:visible="approvalIdVisible"
        :title="t('attributeFrom.approvalIdTitle')"
        :width="610"
        :centered="true"
        :after-close="handleAfterClose"
        @ok="handleApprovalIdOk"
    >
        <div class="x-layout-table">
            <div class="x-layout-table-row">
                <div class="x-layout-table-item fx_base_select">
                    <div class="base-select-list">
                        <div v-for="(item, index) in selectList" :key="index" class="select-item">
                            <a-icon v-if="item.type === 'USER'" class="select-icon select-icon-user" type="user" />
                            <a-icon
                                v-if="item.type === 'USER_GROUP'"
                                class="select-icon select-icon-users"
                                type="team"
                            />
                            <a-icon
                                v-if="item.type === 'DEPARTMENT'"
                                class="select-icon select-icon-apartment"
                                type="apartment"
                            />
                            <span class="">{{ item.name }}</span>
                            <span class="remove-btn">
                                <a-icon type="close" @click="handleRemoveApproval(item, index)" />
                            </span>
                        </div>
                    </div>
                    <div class="base-select-menu">
                        <div
                            v-for="(menu, index) in approvalIdMenu"
                            :key="index"
                            class="select-btn"
                            :class="{
                                select: menu.type === selectApprovalIdMenu
                            }"
                            @click="handleChangeApprovalIdMenu(menu)"
                        >
                            {{ menu.title }}
                        </div>
                        <div class="select-search-pane">
                            <div class="fui-search-input size-small">
                                <a-icon class="icon-search" type="search" />
                                <a-input v-model:value="searchText" class="search-source" />
                                <a-icon
                                    v-show="searchText"
                                    class="icon-close-normal"
                                    type="close"
                                    @click="searchText = ''"
                                />
                            </div>
                        </div>
                    </div>
                    <div class="base-select-pane">
                        <div class="depart-pane">
                            <div v-if="selectApprovalIdMenu" class="select-department">
                                <a-tree
                                    :checked-keys="checkedKeys"
                                    :multiple="true"
                                    :selectable="true"
                                    checkable
                                    :check-strictly="true"
                                    :tree-data="approvalIdList"
                                    :field-names="{ title: 'name', key: 'id' }"
                                    @check="handleChangeCheckedKeys"
                                    @select="handleChangeCheckedKeys"
                                />
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </a-modal>
</template>

<script lang="ts">
    import { cloneDeep } from 'lodash-es'
    import { defineComponent, ref, computed, onMounted, nextTick } from 'vue'
    import { useI18n } from 'vue-i18n'
    import { isNullOrEmpty } from '@/utils/is'
    import type { SelectList, Item, Menu } from '@/types/approvalIdModal'

    export default defineComponent({
        name: 'ApprovalIdModal',
        props: {
            approverList: {
                type: Array,
                default: () => []
            },
            fetchResponse: {
                type: Object,
                default: () => ({})
            },
            onlyDepartment: {
                type: Boolean,
                default: false
            },
            // 审批人类型
            approverType: {
                type: String,
                default: ''
            }
        },
        emits: ['afterClose'],
        setup(props, { emit }) {
            const { t } = useI18n()
            // TODO
            /**
             *创建响应式数据
             */
            //  选中的数据
            const selectList = ref<any[]>([])
            // 选择的审批人类型
            const selectApprovalIdMenu = ref<string | null>('DEPARTMENT')
            const searchText = ref('')
            // 弹层状态
            const approvalIdVisible = ref<boolean>(false)

            /**
             *计算属性
             */
            //  审批类型菜单
            const approvalIdMenu = computed((): SelectList[] => {
                // 选择组织权限的时候仅仅需要展示部门相关的数据,其余的隐藏
                if (props.onlyDepartment) {
                    return [
                        {
                            type: 'DEPARTMENT',
                            key: 'departmentList',
                            title: t('attributeFrom.department')
                        }
                    ]
                    // 审批人类型为指定角色
                } else if (props.approverType === 'DESIGNATED_ROLE') {
                    return [
                        {
                            type: 'ROLE',
                            key: 'roleList',
                            title: t('attributeFrom.role')
                        }
                    ]
                } else {
                    return [
                        {
                            type: 'DEPARTMENT',
                            key: 'departmentList',
                            title: t('attributeFrom.department')
                        },
                        {
                            type: 'USER_GROUP',
                            key: 'userGroupList',
                            title: t('attributeFrom.userGroup')
                        },
                        {
                            type: 'USER',
                            key: 'userList',
                            title: t('attributeFrom.user')
                        }
                    ]
                }
            })

            // 当前审批类型数据列表
            const approvalIdList = computed(() => {
                const { key } = approvalIdMenu.value.find((item: { type: string }) =>
                    [selectApprovalIdMenu.value, 'ROLE'].includes(item.type)
                )
                // 如果没有搜索 就直接返回 否则就查询含有该内容的审批内容
                if (isNullOrEmpty(searchText.value)) {
                    return approvalInfo.value[key].treeData
                } else {
                    return approvalInfo.value[key].originData.filter(item => item.name.indexOf(searchText.value) > -1)
                }
            })

            // 树状结构选中的数组, 依赖于selectList  selectApprovalIdMenu
            const checkedKeys = computed(() => {
                return selectList.value
                    .filter((item: { type: string }) => item.type === selectApprovalIdMenu.value || (item.type === 'DESIGNATED_ROLE' && selectApprovalIdMenu.value === 'DEPARTMENT'))
                    .map((item: { approverId: string }) => item.approverId)
            })

            // 审批人信息
            const approvalInfo = computed(() => {
                const approval = cloneDeep(props.fetchResponse)
                const formatApproval = {}
                approvalIdMenu.value.forEach((menu: Menu) => {
                    formatApproval[menu.key] = {
                        // 原始数据,可用于搜索过滤
                        originData: approval[menu.key],
                        treeData: menu.key === 'departmentList' ? genTree(approval[menu.key]) : approval[menu.key] //树状数据
                    }
                })
                return formatApproval
            })

            /**
             *暴露方法
             */
            // 原始数据生成树状结构
            const genTree = (data = [], parentId = 0) => {
                const res: Item[] = []
                data.forEach((item: Item, _index: number) => {
                    if (item.parentId === parentId) {
                        // 为循环并且使用过的数据增加标记, 优化性能
                        item.used = true
                        const noUesdData = data.filter((dataItem: { used: boolean }) => !dataItem.used)
                        // 递归调用
                        const itemChildren = genTree(noUesdData, item.id)
                        //  itemChildren 如果存在给children赋值
                        if (itemChildren.length) {
                            item.children = itemChildren
                        }
                        res.push(item)
                    }
                })
                return res
            }

            // 打开弹层
            const handleSelectApprovalId = () => {
                approvalIdVisible.value = true
            }

            // 弹框确认方法
            const handleApprovalIdOk = () => {
                approvalIdVisible.value = false
                emit('afterClose', selectList.value)
            }

            // 弹层完全关闭
            const handleAfterClose = () => {
                emit('afterClose', props.approverList)
            }

            // 选择审批审批人、用户组、部门发生变化
            const handleChangeCheckedKeys = ({}, { node }) => {
                const { eventKey, name: title } = node

                if (!node.checked) {
                    //  选中操作
                    ;(selectList.value as Array<SelectList>).push({
                        type: props.approverType === 'DESIGNATED_ROLE' ? props.approverType : (selectApprovalIdMenu.value as string),
                        approverId: eventKey,
                        name: title
                    })
                } else {
                    //  取消操作
                    selectList.value = selectList.value.filter(
                        (item: { approverId: string }) => item.approverId !== eventKey
                    )
                }
            }

            //  删除审批人、用户组、部门
            const handleRemoveApproval = (_approval, index) => {
                // 选中数据框数据更新
                selectList.value.splice(index, 1)
            }

            // 改变审批类型
            const handleChangeApprovalIdMenu = menu => {
                selectApprovalIdMenu.value = null
                nextTick(() => {
                    selectApprovalIdMenu.value = menu.type
                })
            }

            /**
             *生命周期
             */
            onMounted(() => {
                selectList.value = cloneDeep(props.approverList)
                approvalIdVisible.value = true
            })

            /**
             *返回
             */
            return {
                t,
                selectList,
                selectApprovalIdMenu,
                searchText,
                approvalIdVisible,
                approvalIdMenu,
                checkedKeys,
                approvalIdList,
                handleApprovalIdOk,
                handleSelectApprovalId,
                handleAfterClose,
                handleChangeCheckedKeys,
                handleRemoveApproval,
                handleChangeApprovalIdMenu
            }
        }
    })
</script>

<style lang="less" scoped>
    .fx_base_select {
        width: 570px;
        height: 450px;
        position: relative;
    }

    .base-select-list {
        height: 80px;
        border: 1px solid #e0e0e0;
        margin-bottom: 10px;
        overflow: auto;

        .select-empty {
            cursor: pointer;
            line-height: 78px;
            text-align: center;
            color: #989898;
        }

        .select-item {
            display: inline-block;
            line-height: 30px;
            margin: 5px 0 0 5px;
            padding: 0 10px;
            border-radius: 1px;
            background: #f3f6fc;

            .remove-btn {
                cursor: pointer;
                margin-left: 10px;
                padding: 3px;
                color: #999;
            }

            .select-icon {
                font-size: 15px;
                padding-right: 4px;
                vertical-align: middle;
                line-height: 22px;

                &-user {
                    color: #ed5565;
                }

                &-users {
                    color: #248af9;
                }

                &-apartment {
                    color: #fa0;
                }
            }
        }
    }

    .base-select-menu {
        position: relative;
        height: 40px;
        padding: 0 10px;
        border: 1px solid #e0e0e0;

        .select-btn {
            text-align: center;
            display: inline-block;
            cursor: pointer;
            line-height: 38px;
            height: 38px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            padding: 0 5px;
            margin: 0 10px;

            &.select {
                color: #1890ff;
                border-bottom: solid 4px #1890ff;
            }
        }

        .select-search-pane {
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            padding: 0 10px;
            width: 114px;
            background: #fff;

            &.full-line {
                width: 100%;
            }
        }

        .fui-search-input {
            position: relative;
            line-height: 32px;
            margin-top: 6px;

            .icon-search {
                position: absolute;
                top: 6px;
                left: 10px;
                color: #5e6d82;
                font-size: 16px;
                z-index: 1;
            }

            .icon-close-normal {
                position: absolute;
                top: 6px;
                right: 10px;
                color: #5e6d82;
                font-weight: 700;
                z-index: 1;
            }

            .search-source {
                display: block;
                height: 26px;
                padding: 5px 28px;
                line-height: 16px;
                border-radius: 13px;
                background: #f4f4f4;
            }

            &.size-small {
                line-height: 26px;
            }
        }
    }

    .base-select-pane {
        border: 1px solid #e0e0e0;
        border-top: none;
        position: absolute;
        top: 130px;
        left: 0;
        bottom: 0;
        right: 0;

        .depart-pane {
            height: 100%;
            position: relative;
            overflow: hidden;
        }

        .x-tree-check {
            position: absolute;
            top: 0;
            right: 5px;
        }

        .select-department {
            position: absolute;
            top: 0;
            left: 0;
            bottom: 0;
            right: 0;
            overflow: auto;
            padding: 5px 0;

            :deep(.@{ant-prefix}-tree li span.@{ant-prefix}-tree-checkbox) {
                float: right;
                margin-right: 15px;
            }

            :deep(.@{ant-prefix}-tree li .@{ant-prefix}-tree-node-content-wrapper.@{ant-prefix}-tree-node-selected) {
                background: none;
            }

            .select-department-item {
                position: relative;
                white-space: nowrap;
                line-height: 14px;
                text-align: left;
                outline: 0;

                &--warp {
                    padding: 0 7px;
                    padding-right: 30px;
                    cursor: pointer;
                    display: inline-block;
                    width: 100%;
                    height: 26px;
                    line-height: 26px;
                }
            }
        }
    }
</style>

<i18n>
zh-CN:
  attributeFrom:
    approvalIdTitle: '部门成员列表'
    department: '部门'
    role: '角色'
    userGroup: '用户组'
    user: '人员'
en-US:
  attributeFrom:
    approvalIdTitle: 'Department member list'
    department: 'department'
    role: 'role'
    userGroup: 'User group'
    user: 'personnel'
</i18n>
